﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using YArchitech.HVAC;
using YArchitech.LIB;
using YArchitech.MEP;
using YArchitech.Revit;
using YRevitJig;

namespace YArchitech.Plumbing
{
	public class RiserPipeExecute
	{
		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public RiserPipeExecute(YJKWindowHandle HWndRevit, XAuxiliaryFrameJig Auxjig, bool IsHVAC)
		{
			RiserPipeExecute.hWndRevit = HWndRevit;
			this.auxjig = Auxjig;
			this.isHVAC = IsHVAC;
		}

		public Result Execute(ExternalCommandData commandData)
		{
			FormReiseDrawVerticalPipe formReiseDrawVerticalPipe = null;
			Transaction transaction = null;
			double zStart = 0.0;
			double zEnd = 0.0;
			PipeType pipeTypeRiser = null;
			PipingSystemType pipingSystemTypeRiser = null;
			string diameter = "0";
			RiserPipeOperation riserPipeOperation = new RiserPipeOperation();
			string text = "";
			Pipe pipe = null;
			UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
			UIApplication application = commandData.Application;
			Autodesk.Revit.ApplicationServices.Application application2 = application.Application;
			Document document = application.ActiveUIDocument.Document;
			Transaction transaction2 = new Transaction(document, "添加共享参数");
			transaction2.Start();
			MarkOperation markOperation = new MarkOperation();
			markOperation.AddAllShareParametes(application);
			transaction2.Commit();
			markOperation.SetActiveDocAllLoadedTags(document);
			Result result;
			try
			{
				AuxiliaryFrameOperation auxiliaryFrameOperation = new AuxiliaryFrameOperation();
				List<ViewType> viewTypes = YJKRevitTools.ListViewNeed(1);
				if (!YJKRevitTools.ViewCheck(activeUIDocument, viewTypes))
				{
					result = Autodesk.Revit.UI.Result.Cancelled;
				}
				else
				{
					transaction = new Transaction(document, "布置水管立管");
					transaction.Start();
					formReiseDrawVerticalPipe = this.ShowFormReiseDrawVerticalPipe(RiserPipeExecute.hWndRevit, document, riserPipeOperation, this.isHVAC);
					for (;;)
					{
						string empty = string.Empty;
						pipe = this.LayRiserPipe(formReiseDrawVerticalPipe, document, zStart, zEnd, pipeTypeRiser, pipingSystemTypeRiser, diameter, activeUIDocument, auxiliaryFrameOperation, ref empty, riserPipeOperation);
						if (pipe != null)
						{
							if (formReiseDrawVerticalPipe.hyTextBox2.Text != "")
							{
								text = formReiseDrawVerticalPipe.hyTextBox2.Text;
							}
							riserPipeOperation.SetMark(auxiliaryFrameOperation.SetAuxiliaryFramePipe(activeUIDocument.Document, pipe, formReiseDrawVerticalPipe.isAuxiliaryFrame, formReiseDrawVerticalPipe.length, empty), activeUIDocument, formReiseDrawVerticalPipe, application, auxiliaryFrameOperation);
							document.Regenerate();
						}
					}
				}
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				if (pipe != null)
				{
					Parameter parameter = pipe.GetParameter("立管编号");
					if (parameter == null || string.IsNullOrEmpty(parameter.AsString()))
					{
						XYZ point = null;
						RiserPipeAndCenter riserPipeAndCenter = new RiserPipeAndCenter(pipe, point);
						if (Regex.IsMatch(text, "^[0-9]+$"))
						{
							MarkRiserPipeUtility.SetRiserPipeParameters(application, riserPipeAndCenter.RiserPipe, "", text, formReiseDrawVerticalPipe.rbCuston.Checked, false);
						}
					}
				}
				if (!formReiseDrawVerticalPipe.IsDisposed)
				{
					formReiseDrawVerticalPipe.Dispose();
				}
				if (this.auxjig != null)
				{
					this.auxjig.Dispose();
				}
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message, "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
				this.EndTransation(transaction, false);
				result = Autodesk.Revit.UI.Result.Failed;
			}
			finally
			{
				this.EndTransation(transaction, true);
			}
			return result;
		}

		private Pipe LayRiserPipe(FormReiseDrawVerticalPipe drawPipeForm, Document doc, double zStart, double zEnd, PipeType pipeTypeRiser, PipingSystemType pipingSystemTypeRiser, string diameter, UIDocument uidoc, AuxiliaryFrameOperation afOperation, ref string strIds, RiserPipeOperation rpOperation)
		{
			ICollection<ElementId> allPipe;
			using (this.auxjig = new XAuxiliaryFrameJig(uidoc))
			{
				this.auxjig.length = drawPipeForm.length;
				this.auxjig.angle = drawPipeForm.angle;
				this.auxjig.isAuxiliaryFrame = drawPipeForm.isAuxiliaryFrame;
				this.auxjig.diameter = Convert.ToDouble(drawPipeForm.comboBox_DN.SelectedItem);
				XYZ xyz = this.PickPoint(this.auxjig, this.auxjig.PickAuxiliaryFramePoint("请选择布置立管的点"));
				if (!drawPipeForm.onDraw(true))
				{
					return null;
				}
				strIds = rpOperation.CreateAuxiliaryFrame(drawPipeForm.isAuxiliaryFrame, uidoc, xyz, drawPipeForm.length, drawPipeForm.angle, afOperation);
				rpOperation.SetParament(ref zStart, ref zEnd, ref pipeTypeRiser, ref pipingSystemTypeRiser, ref diameter, drawPipeForm);
				allPipe = this.GetAllPipe(doc);
				new HYCreatePipeHelper().DrawRiserPipe(xyz.X, xyz.Y, zStart, zEnd, doc, pipeTypeRiser, diameter, pipingSystemTypeRiser, "");
				this.auxjig.Dispose();
			}
			return this.getRiserPipe(allPipe, doc);
		}

		private XYZ PickPoint(XAuxiliaryFrameJig auxjig, XYZ xyz)
		{
			if (auxjig.isAuxiliaryFrame)
			{
				double num = AssistFunc.mmToFeet(auxjig.length);
				if (auxjig.JigStage == XAuxiliaryFrameJig.EStage.eLeftUpPt)
				{
					xyz = xyz.Add(num / 2.0 * auxjig.xVector).Add(-num / 2.0 * auxjig.yVector);
				}
				else if (auxjig.JigStage == XAuxiliaryFrameJig.EStage.eLeftDownPt)
				{
					xyz = xyz.Add(num / 2.0 * auxjig.xVector).Add(num / 2.0 * auxjig.yVector);
				}
				else if (auxjig.JigStage == XAuxiliaryFrameJig.EStage.eRightDownOper)
				{
					xyz = xyz.Add(-num / 2.0 * auxjig.xVector).Add(num / 2.0 * auxjig.yVector);
				}
				else if (auxjig.JigStage == XAuxiliaryFrameJig.EStage.eRightUpOper)
				{
					xyz = xyz.Add(-num / 2.0 * auxjig.xVector).Add(-num / 2.0 * auxjig.yVector);
				}
			}
			return xyz;
		}

		private Pipe getRiserPipe(ICollection<ElementId> collectionId, Document doc)
		{
			doc.Regenerate();
			Pipe result = null;
			ICollection<ElementId> allPipe = this.GetAllPipe(doc);
			new List<ElementId>();
			foreach (ElementId item in collectionId.Intersect(allPipe))
			{
				allPipe.Remove(item);
			}
			if (allPipe != null && allPipe.Count > 0)
			{
				result = (doc.GetElementById(allPipe.FirstOrDefault<ElementId>()) as Pipe);
			}
			return result;
		}

		public ICollection<ElementId> GetAllPipe(Document doc)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			new ElementOwnerViewFilter(doc.ActiveView.Id);
			return filteredElementCollector.OfClass(typeof(Pipe)).ToElementIds();
		}

		private FormReiseDrawVerticalPipe ShowFormReiseDrawVerticalPipe(YJKWindowHandle hWndRevit, Document doc, RiserPipeOperation rpOperation, bool isHVAC)
		{
			FormReiseDrawVerticalPipe formReiseDrawVerticalPipe = new FormReiseDrawVerticalPipe(doc, rpOperation.GetLevelUp(doc), rpOperation.GetPipeType(doc), rpOperation.GetPipingSystemType(doc), isHVAC);
			formReiseDrawVerticalPipe.Show(hWndRevit);
			int wMsg = 7;
			RiserPipeExecute.SendMessage(RiserPipeCreate.hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			formReiseDrawVerticalPipe.AuxiliaryFrameEvent += this.DrawPipeForm_AuxiliaryFrameEvent;
			return formReiseDrawVerticalPipe;
		}

		private void DrawPipeForm_AuxiliaryFrameEvent(object sender, AuxiliaryFrameArgs e)
		{
			if (e.Type == senderType.check)
			{
				this.auxjig.isAuxiliaryFrame = Convert.ToBoolean(sender);
				return;
			}
			if (e.Type == senderType.length)
			{
				this.auxjig.length = Convert.ToDouble(sender);
				return;
			}
			if (e.Type == senderType.diameter)
			{
				this.auxjig.diameter = Convert.ToDouble(sender);
				return;
			}
			if (e.Type == senderType.angle)
			{
				this.auxjig.angle = Convert.ToDouble(sender);
			}
		}

		private void EndTransation(Transaction tran, bool beSure)
		{
			if (tran != null)
			{
				TransactionStatus status = tran.GetStatus();
				if ((int)status == 1)
				{
					if (beSure)
					{
						tran.Commit();
						return;
					}
					tran.RollBack();
					return;
				}
				else if ((int)status == 5)
				{
					tran.RollBack();
				}
			}
		}

		public static YJKWindowHandle hWndRevit;

		private XAuxiliaryFrameJig auxjig;

		private bool isHVAC;
	}
}
